package org.my.workflow.element;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Collections;

import org.my.workflow.WorkflowException;
import org.w3c.dom.Element;

/**
 * @author <a href="mailto:yang_y@sysnet.com.cn">Young Yang</a>
 */
public class ActionElement implements ConfigElement {

    protected List<ConditionElement> conditionElements = new ArrayList<ConditionElement>();
    protected List<InterceptorElement> preInterceptors = new ArrayList<InterceptorElement>();
    protected List<InterceptorElement> postInterceptors = new ArrayList<InterceptorElement>();

    protected List<TargetStepElement> conditionalTargetSteps = new ArrayList<TargetStepElement>();
    protected TargetStepElement unconditionalTargetStep;

    protected List validators = new ArrayList();
    protected Map metaAttributes = new HashMap();

    protected String id;
    protected String name;
    protected String stepElementId;

    protected String view;
    protected boolean autoExecute = false;
    protected boolean common;
    protected boolean finish = false;

    public void processXML(Element element) {
        id = XMLUtils.getAtrributeValue(element, "id");
        name = XMLUtils.getAtrributeValue(element, "name");

        Element conditionsXMLElement = XMLUtils.getChildElementByTagName(element, "conditions");
        if (conditionsXMLElement != null) {
            List<Element> conditionXMLElements = XMLUtils.getChildElementsByTagName(conditionsXMLElement, "condition");
            for (Element conditionXMLElement : conditionXMLElements) {
                ConditionElement conditionElement = new ConditionElement();
                conditionElement.processXML(conditionXMLElement);
                conditionElements.add(conditionElement);
            }
        }

        Element preActionXMLElement = XMLUtils.getChildElementByTagName(element, "pre-action");
        if (preActionXMLElement != null) {
            List<Element> preInterceptorXMLElements = XMLUtils.getChildElementsByTagName(preActionXMLElement, "interceptor");
            for (Element preIntercElement : preInterceptorXMLElements) {
                InterceptorElement interceptorElement = new InterceptorElement();
                interceptorElement.processXML(preIntercElement);
                preInterceptors.add(interceptorElement);
            }
        }

        Element postActionXMLElement = XMLUtils.getChildElementByTagName(element, "post-action");
        if (postActionXMLElement != null) {
            List<Element> postInterceptorXMLElements = XMLUtils.getChildElementsByTagName(postActionXMLElement, "interceptor");
            for (Element postIntercElement : postInterceptorXMLElements) {
                InterceptorElement interceptorElement = new InterceptorElement();
                interceptorElement.processXML(postIntercElement);
                postInterceptors.add(interceptorElement);
            }
        }

        List<Element> targetStepXMLElements = XMLUtils.getChildElementsByTagName(element, "target-step");
        for (Element targetStepXMLElement : targetStepXMLElements) {
            TargetStepElement targetStepElement = new TargetStepElement();
            targetStepElement.processXML(targetStepXMLElement);
            if (targetStepElement.isConditional()) {
                conditionalTargetSteps.add(targetStepElement);
            }
            else {
                if (unconditionalTargetStep == null) {
                    unconditionalTargetStep = targetStepElement;
                }
                else {
                    throw new WorkflowException("Only one unconditional target-step in action allowed!");
                }
            }
        }
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getStepElementId() {
        return stepElementId;
    }

    void setStepElementId(String stepElementId) {
        this.stepElementId = stepElementId;
    }

    public List<ConditionElement> getConditionElements() {
        return Collections.unmodifiableList(conditionElements);
    }

    public List<InterceptorElement> getPreInterceptorElements() {
        return Collections.unmodifiableList(preInterceptors);
    }

    public List<InterceptorElement> getPostInterceptorElements() {
        return Collections.unmodifiableList(postInterceptors);
    }

    public TargetStepElement getUnconditionalTargetStepElement() {
        return unconditionalTargetStep;
    }

    public List<TargetStepElement> getConditionalTargetStepElements() {
        return Collections.unmodifiableList(conditionalTargetSteps);
    }

    public String toString() {
        return super.toString() + "[" + name +"]";
    }
}
